﻿
Imports System.Reflection

Public Class fieldvalues(Of T)
    Private ReadOnly v() As fieldvalue(Of T) = Nothing

    Private Delegate Function ctor_d(ByVal t As Type,
                                     ByVal bindingFlags As BindingFlags,
                                     ByVal obj As Object,
                                     ByVal name As String) As fieldvalue(Of T)

    Private Sub New(ByVal t As Type,
                    ByVal bindingFlags As BindingFlags,
                    ByVal obj As Object,
                    ByVal names() As String,
                    ByVal ctor As ctor_d)
        assert(Not ctor Is Nothing)
        If Not names Is Nothing AndAlso names.Length > 0 Then
            ReDim v(names.Length() - 1)
            For i As Int32 = 0 To names.Length() - 1
                v(i) = ctor(t, bindingFlags, obj, names(i))
            Next
        End If
    End Sub

    Public Sub New(ByVal t As Type,
                   ByVal bindingFlags As BindingFlags,
                   ByVal obj As Object,
                   ByVal ParamArray names() As String)
        Me.New(t, bindingFlags, obj, names, Function(a, b, c, d) New fieldvalue(Of T)(a, b, c, d))
    End Sub

    Public Sub New(ByVal t As Type, ByVal bindingFlags As BindingFlags, ByVal ParamArray names() As String)
        Me.New(t, bindingFlags, Nothing, names, Function(a, b, c, d) New fieldvalue(Of T)(a, b, d))
    End Sub

    Public Sub New(ByVal t As Type, ByVal ParamArray names() As String)
        Me.New(t, Nothing, Nothing, names, Function(a, b, c, d) New fieldvalue(Of T)(a, d))
    End Sub

    Public Sub New(ByVal t As Type, ByVal obj As Object, ByVal ParamArray names() As String)
        Me.New(t, Nothing, obj, names, Function(a, b, c, d) New fieldvalue(Of T)(a, c, d))
    End Sub

    Public Sub New(ByVal obj As Object, ByVal ParamArray names() As String)
        Me.New(Nothing, Nothing, obj, names, Function(a, b, c, d) New fieldvalue(Of T)(c, d))
    End Sub

    Public Sub New(ByVal obj As Object, ByVal bindingFlags As BindingFlags, ByVal ParamArray names() As String)
        Me.New(Nothing, bindingFlags, obj, names, Function(a, b, c, d) New fieldvalue(Of T)(b, c, d))
    End Sub

    Public Sub New(ByVal bindingFlags As BindingFlags, ByVal obj As Object, ByVal ParamArray names() As String)
        Me.New(Nothing, bindingFlags, obj, names, Function(a, b, c, d) New fieldvalue(Of T)(b, c, d))
    End Sub

    Default Public ReadOnly Property at(ByVal i As Int32) As T
        Get
            Return +v(i)
        End Get
    End Property

    Public Function size() As Int32
        Return v.Length()
    End Function
End Class
